Skip to content

feat(http): add SSE streaming support via Client.Stream - #107

Open
sunfuze wants to merge 1 commit into
mainfrom
feat-http-sse-stream
Open

feat(http): add SSE streaming support via Client.Stream#107
sunfuze wants to merge 1 commit into
mainfrom
feat-http-sse-stream

Conversation

@sunfuze

@sunfuze sunfuze commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Add server-sent events (SSE) support to the http package.

  • Client.Stream sends a request with Accept: text/event-stream and returns a pull-based *Stream. Request build errors, connection failures and non-200 responses (*ApiError) are returned synchronously from the call.
  • Stream follows the bufio.Scanner / sql.Rows idiom (same shape as anthropic-sdk-go / openai-go SSE streams): Next() / Current() / Err() / Close() — no background goroutine, no locks, natural backpressure. Mid-stream read failures, timeouts and cancellation are reported by Err.
  • Events() returns an iter.Seq[[]byte] (range-over-func) adapter yielding each event's data payload — multiple data: lines are joined with \n; comments/heartbeats and non-data fields (event:/id:/retry:) are skipped.
  • Streaming uses a shallow copy of the configured http.Client with Timeout cleared, since http.Client.Timeout caps the entire request (headers + body read) and would kill a long-lived stream; the stream's lifetime is bounded by the caller's ctx instead.
  • Refactor: extract request building/signing from Call into newRequest, shared by Call and Stream (no behavior change for Call).

Usage

stream, err := client.Stream(ctx, "GET", "/v1/xxx", nil, nil)
if err != nil {
    return err
}
defer stream.Close()

for data := range stream.Events() {
    // handle each event payload
}
if err := stream.Err(); err != nil {
    // read failure / timeout / cancellation
}

Test plan

  • http/stream_test.go (httptest-based): multi-line data events, CRLF lines, comment/heartbeat skipping, trailing event without blank line, iterator + early break, non-200 → *ApiError, context timeout surfaced via Err(), connect failure, Close() idempotency
  • GOWORK=off go test ./http/ -race — all green
  • GOWORK=off go vet ./http/ — clean

🤖 Generated with Claude Code

Add server-sent events (SSE) support to the http package:

- Client.Stream sends a request with "Accept: text/event-stream" and
  returns a pull-based *Stream; request/connection errors and non-200
  responses (*ApiError) are returned synchronously.
- Stream follows the bufio.Scanner / sql.Rows style: Next / Current /
  Err / Close, plus an Events() iter.Seq[[]byte] adapter for
  range-over-func consumption. Mid-stream read failures, timeouts and
  cancellation are reported by Err.
- Streaming uses a copy of the configured http.Client with Timeout
  cleared, since http.Client.Timeout caps the whole request and would
  abort a long-lived stream; the lifetime is bounded by ctx instead.
- Extract request building/signing from Call into newRequest, shared
  by Call and Stream.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sunfuze
sunfuze requested a review from Patrick0308 July 12, 2026 05:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant